package com.google.code.mc4java.msg;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;



public abstract class AbstractTextMessage implements Message {
	
	
	public abstract byte[] createMessage(String key,Object value,long timeout,String cmd);

	public abstract byte[] createMessage(String key,String cmd);
	
	public abstract byte[] getMsg();
	
	public abstract Object parseMessage(int flag,byte[] value);
	
	protected int flag = 1;
	
	protected String sanitizeKey( String key ) throws UnsupportedEncodingException {
		return URLEncoder.encode( key, "UTF-8" );
	}	
	
	@SuppressWarnings("unused")
	protected byte[] encodeMsg(Object value) {
		byte[] buf = null;
		int len;
		if(value instanceof String) {
			flag = 1;
			buf = ((String) value).getBytes();
			len = buf.length;
		} else if(value instanceof Boolean) {
			flag = 2;
			buf = ((Boolean) value).toString().getBytes();
			len = buf.length;			
		} else if(value instanceof Integer) {
			flag = 3;
			buf = ((Integer) value).toString().getBytes();
			len = buf.length;
		} else if(value instanceof Long) {
			flag = 4;
			buf = ((Long) value).toString().getBytes();
			len = buf.length;
		} else if(value instanceof Float) {
			flag = 5;
			buf = ((Float) value).toString().getBytes();
			len = buf.length;
		} else if(value instanceof Double) {
			flag = 6;
			buf = ((Double) value).toString().getBytes();
			len = buf.length;
		} else {
			flag = 7;
			buf = serialObj(value);
			len = buf.length;
		}
		return buf;
	}
	
	protected byte[] serialObj(Object value) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(value);
			byte[] buf = baos.toByteArray();
			baos.close();
			oos.close();
			return buf;
		} catch(Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	protected Object deserialObj(byte[] value) {
		try {
			ByteArrayInputStream bais = new ByteArrayInputStream(value);
			ObjectInputStream ois = new ObjectInputStream(bais);
			Object obj = ois.readObject();
			bais.close();
			ois.close();
			return obj;
		} catch(Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	protected Object decode(int flag,byte[] value) {
		switch(flag) {
			case 1:
				return new String(value);
			case 2:
				return Boolean.parseBoolean(new String(value));
			case 3:
				return Integer.parseInt(new String(value));
			case 4:
				return Long.parseLong(new String(value));
			case 5:
				return Float.parseFloat(new String(value));
			case 6:
				return Double.parseDouble(new String(value));
			case 7:
				return deserialObj(value);
				
		}
		return null;
	}

	public int getFlag() {
		return flag;
	}
	
}
